package com.thoughtworks.mobinium.android;

import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.util.Map;

import org.antlr.runtime.ANTLRInputStream;
import org.antlr.runtime.CommonTokenStream;
import org.antlr.runtime.tree.Tree;

import android.app.Activity;
import android.app.Instrumentation;
import android.os.Bundle;
import android.util.Log;

import com.thoughtworks.mobinium.TestResultPrinter;
import com.thoughtworks.mobinium.parser.AstProcessor;
import com.thoughtworks.mobinium.parser.MobiniumLexer;
import com.thoughtworks.mobinium.parser.MobiniumParser;
import com.thoughtworks.mobinium.parser.MobiniumParser.statements_return;

public class TestRunner extends Instrumentation {

	private Tree tree;
	private String resultsFile;

	@Override
	public void onCreate(Bundle arguments) {
		super.onCreate(arguments);
		try {
			ANTLRInputStream input = new ANTLRInputStream(getTestScript());
			MobiniumLexer lexer = new MobiniumLexer(input);
			CommonTokenStream tokens = new CommonTokenStream(lexer);
			MobiniumParser parser = new MobiniumParser(tokens);
			statements_return statementsReturn = parser.statements();
			tree = (Tree) statementsReturn.getTree();
			resultsFile = arguments.getString("results");
			if (resultsFile == null) {
				resultsFile = "testresults";
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}

		Log.i("Finished parsing antlr script", "");
		// When this instrumentation is created, we simply want to start
		// its test code off in a separate thread, which will call back
		// to us in onStart().
		start();
	}

	protected InputStream getTestScript() {
		return null;
	}

	@Override
	public void onStart() {

		try {
			AndroidScriptVisitor visitor = new AndroidScriptVisitor(this);
			new AstProcessor(visitor).accept(tree);
			Map<String, String> testResults = visitor.getResults();
			writeToFile(testResults);
			finish(Activity.RESULT_OK, new Bundle());
		} catch (Exception ex) {
			throw new RuntimeException(ex);
		}
	}

	private void writeToFile(Map<String, String> testResults)
			throws IOException {
		deleteFileIfExists();
		FileOutputStream file = getContext().openFileOutput(resultsFile, 0);
                PrintStream output = new PrintStream(new BufferedOutputStream(
				file));
		new TestResultPrinter(output).print(testResults);
		file.close();
	}

	private void deleteFileIfExists() {
		try {
			getContext().deleteFile(resultsFile);
		} catch (Exception ex) {

		}
	}
}
